import { acceptHMRUpdate, defineStore } from "pinia";
import { shallowRef } from "vue";
import type { JdkVersionInfo } from "@/pages/tools/java/types";
import { existsFile, readDir, readFileText } from "@/framework/util/fs";
import path from "path-browserify-esm";
import { useLocalRef } from "@/framework/vue/hooks";

class JdkReleaseFile {
  private _values: Dict<string> = {};

  constructor(public path: string) {}

  async load() {
    const text = await readFileText(this.path);
    const lines = text.split("\n");
    for (let line of lines) {
      line = line.trim();
      if (!line) continue;
      const [key, value] = line.split("=");
      this._values[key] = value?.replace(/^"|"$/g, "");
    }
  }

  get(key: string) {
    return this._values[key];
  }
}

const defaultInstallPath = "C:/Dev/Denv/Java";

export const useJdkStore = defineStore("java-jdk", () => {
  const installPath = useLocalRef("java.jdk.install.path", defaultInstallPath);
  const setInstallPath = (path: string) => (installPath.value = path);

  const versionList = shallowRef<JdkVersionInfo[]>([]);

  async function scanInstalledJdk() {
    try {
      const list: JdkVersionInfo[] = [];
      const variants = await readDir(installPath.value);
      for (const variant of variants) {
        const varitantDir = path.join(installPath.value, variant);
        const items = await readDir(varitantDir);
        for (const it of items) {
          const dir = path.join(varitantDir, it);
          const javaExeFile = path.join(dir, "bin/java.exe");
          try {
            const existsExeFilePath = await existsFile(javaExeFile);
            if (!existsExeFilePath) continue;
            const releaseFilePath = path.join(dir, "release");
            const existsReleaseFile = await existsFile(releaseFilePath);
            if (!existsReleaseFile) continue;
            const releaseFile = new JdkReleaseFile(releaseFilePath);
            await releaseFile.load();
            list.push({
              path: dir,
              version: releaseFile.get("JAVA_VERSION"),
              versionDate: releaseFile.get("JAVA_VERSION_DATE"),
              implementor: releaseFile.get("IMPLEMENTOR"),
              variant: releaseFile.get("JVM_VARIANT"),
            });
          } catch (e: any) {
            // ignored
          }
        }
      }

      versionList.value = list;
    } catch (e: any) {
      console.error("scanInstalledJdk error", e);
      versionList.value = [];
    }
  }

  return {
    installPath: installPath,
    setInstallPath: setInstallPath,

    versionList: versionList,
    scanInstalledJdk: scanInstalledJdk,
  };
});

if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useJdkStore, import.meta.hot));
}
